/* Turska UI library
 * Copyright 2003-2008 Jetro Lauha
 * All rights reserved.
 * Web: http://iki.fi/jetro/ or http://jet.ro
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of EITHER:
 *   (1) The GNU Lesser General Public License as published by the Free
 *       Software Foundation; either version 2.1 of the License, or (at
 *       your option) any later version. The text of the GNU Lesser
 *       General Public License is included with this library in the
 *       file LICENSE-LGPL.txt.
 *   (2) The BSD-style license that is included with this library in
 *       the file LICENSE-BSD.txt.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
 * LICENSE-LGPL.txt and LICENSE-BSD.txt for more details.
 *
 * $Id: UIImage.h,v 1.10 2008/03/27 11:44:24 tonic Exp $
 * $Revision: 1.10 $
 */

#ifndef UIIMAGE_H_INCLUDED
#define UIIMAGE_H_INCLUDED


//! Abstract interface for a container of a static UI image.
/*! \note Particular implementation of this class may not support all
 *        features defined by the interface.
 */
class UIImage
{
public:

    //! Image drawing modes.
    enum DRAW_MODE
    {
        NORMAL = 0, //!< Normal image drawing, with alpha if supported.
        ADD,        //!< Additive image drawing.
        MULTIPLY,   //!< Multiplicative image drawing.
        //! Count of image drawing modes.
        DRAW_MODE_COUNT     // Do not add new draw modes after this one.
    };

    //! Drawing flags for image features to use when drawing.
    enum FLAGS
    {
        //! Multiplies source image with color and alpha value when drawing.
        COLOR               = (1 << 0),
        /*! Enables transformation. Drawing uses just target width & height
         *  when disabled and ROTATE, CENTER and SCALE flags when enabled.
         */
        TRANSFORM           = (1 << 1),
        //! Rotates image when drawing.
        ROTATE              = (1 << 2),
        //! Uses center or given pivot of the image as origin instead of top-left corner.
        CENTER              = (1 << 3),
        //! Applies scaling to image. See setScale() methods.
        SCALE               = (1 << 4),

        //! Uses bilinear filtering for image sampling if available.
        /*! Currently this flag can be set only when loading images.
         */
        FILTER_LINEAR   = (1 << 16),
        //! Configures image wrapping to be clamped. Default is to repeat.
        /*! Currently this flag can be set only when loading images.
         */
        WRAP_CLAMP      = (1 << 17),
        /*! Default set of flags for image.
         * Note that the CENTER flag is default for the mode where TRANSFORM
         * is enabled manually. Without manual enabling of TRANSFORM for the
         * image, the CENTER doesn't affect at all.
         */
        DEFAULT_FLAGS   = COLOR | CENTER | WRAP_CLAMP
    };

    //! Constructor initializes image with given values.
    /*! \note The CENTER flag in default flags doesn't apply until the
     *        TRANSFORM flag is separately enabled as well.
     * \param width width of the image.
     * \param height height of the image.
     * \param drawMode initial drawing mode to use, default is NORMAL.
     * \param flags initial flags to use, default is (COLOR | CENTER).
     */
    UIImage(UINT32 width, UINT32 height,
            UINT drawMode = NORMAL,
            UINT32 flags = DEFAULT_FLAGS) :
        mWidth(width), mHeight(height), mFlags(flags), mDrawMode(drawMode) {}
    virtual ~UIImage() {}

    inline UINT32 getWidth() { return mWidth; }
    inline UINT32 getHeight() { return mHeight; }

    inline void setFlags(UINT32 flags) { mFlags = flags; }
    inline UINT32 getFlags() const { return mFlags; }
    inline void setFlag(UINT32 flag) { mFlags |= flag; }
    inline void clearFlag(UINT32 flag) { mFlags &= ~flag; }
    inline void setFlagState(UINT32 flag, BOOL enabled)
    { enabled ? setFlag(flag) : clearFlag(flag); }
    inline BOOL isFlag(UINT32 flag) const { return (mFlags & flag) == flag; }

    //! Sets drawing mode. \sa DRAW_MODE
    inline void setDrawMode(UINT drawMode) { mDrawMode = drawMode; }
    //! Returns current drawing mode. \sa DRAW_MODE
    inline UINT getDrawMode() { return mDrawMode; }

    //! Sets color and alpha to use when COLOR flag is enabled.
    /*! \note Values are specified in range [0..255].
     */
    virtual void setColor(UINT8 red, UINT8 green, UINT8 blue, UINT8 alpha) = 0;
    //! Sets color and alpha to use when COLOR flag is enabled.
    /*! \note Values are specified in range [0..1].
     */
    virtual void setColor(FLOAT red, FLOAT green, FLOAT blue, FLOAT alpha) = 0;

    //! Sets target rectangle size to use when TRANSFORM flag is disabled.
    /*! \note Value scale is the display unit size in use, typically pixels.
     */
    virtual void setTargetSize(UINT32 width, UINT32 height) = 0;
    //! Sets target rectangle size to use when TRANSFORM flag is disabled.
    /*! \note Value scale is the display unit size in use, typically pixels.
     */
    virtual void setTargetSize(FLOAT width, FLOAT height) = 0;

    //! Sets rotation angle to use when ROTATE flag is enabled.
    /*! \param angle rotation angle in radians.
     */
    virtual void setAngle(FLOAT angle) = 0;

    //! Sets the scaling factor to use when SCALE flag is enabled.
    virtual void setScale(FLOAT scale) = 0;

    //! Sets non-uniform scaling factors to use when SCALE flag is enabled.
    virtual void setScale(FLOAT scaleX, FLOAT scaleY) = 0;

    //! Sets pivot to use when CENTER flag is enabled. Default is the center of image.
    virtual void setPivot(FLOAT centerX, FLOAT centerY) = 0;


    //! Draws image with top-left corner position of (x,y).
    virtual void draw(INT32 x, INT32 y) = 0;
    //! Draws image with top-left corner position of (x,y).
    virtual void draw(FLOAT x, FLOAT y) = 0;

    //! Draws image using given drawing mode and flags.
    virtual void draw(UINT drawMode, UINT32 flags, INT32 x, INT32 y) = 0;
    //! Draws image using given drawing mode and flags.
    virtual void draw(UINT drawMode, UINT32 flags, FLOAT x, FLOAT y) = 0;

    //! Draws image using given drawing mode, flags, color and alpha.
    virtual void draw(UINT drawMode, UINT32 flags, FLOAT x, FLOAT y,
                      FLOAT red, FLOAT green, FLOAT blue, FLOAT alpha) = 0;

    //! Draws image using given drawing mode, flags, color and alpha.
    /*! The color parameter array should have 4 floats with values for
     *  red, green, blue and alpha respectively.
     */
    virtual void draw(UINT drawMode, UINT32 flags, FLOAT x, FLOAT y,
                      const FLOAT *color) = 0;

protected:

    UINT32 mWidth;      //!< Image width.
    UINT32 mHeight;     //!< Image height.
    UINT32 mFlags;      //!< Current flag state. \sa FLAGS
    UINT mDrawMode;     //!< Current drawing mode. \sa DRAW_MODE
};


#endif // !UIIMAGE_H_INCLUDED
